﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Ordinaire.Db;
using Ordinaire.Security.Data;

namespace Ordinaire.Security
{
    public class UserDataManager : DataManager<OContext>
    {
        /// <summary>
        /// Add new user with the specified username and password.
        /// </summary>
        /// <param name="name">username</param>
        /// <param name="password">user password</param>
        /// <returns>data created</returns>
        public Users Insert(string name, string password)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            if (String.IsNullOrEmpty(password))
            {
                throw new ArgumentNullException("password");
            }

            // Username already exists.
            if (Exists(name))
            {
                ExceptionFactory.Create<OException>(ExceptionMessage.AlreadyExists, String.Format("Username '{0}'", name));
            }

            Users data = new Users
            {
                Name      = name,
                Password  = Cryptographer.Hash(password),
                CreatedBy = DefaultUserId
            };

            OContext context = Context;
            context.Users.InsertOnSubmit(data);
            context.SubmitChanges();

            return data;
        }

        /// <summary>
        /// Returns a value indicating whether the specified username already exists.
        /// </summary>
        /// <param name="name">username</param>
        /// <returns>true if exists, else false</returns>
        public bool Exists(string name)
        {
            return base.ExistsByName<Users, int, string>(name);
        }

        /// <summary>
        /// Returns data with the specified username.
        /// </summary>
        /// <param name="name">name</param>
        /// <returns>a match from the table or throws exception if returns more than one elements</returns>
        public Users GetByName(string name)
        {
            return base.GetByName<Users, int, string>(name);
        }

        /// <summary>
        /// Returns list of data that matches with the specified array of usernames.
        /// </summary>
        /// <param name="names">array of names</param>
        /// <returns>list of matching data</returns>
        public List<Users> GetByNames(string[] names)
        {
            return base.GetByNames<Users, int, string>(names);
        }
    }
}
